package com.java1234.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.java1234.common.constant.Constant;
import com.java1234.entity.*;
import com.java1234.service.*;
import com.java1234.util.DateUtil;
import com.java1234.util.StringUtil;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.*;
/**
 * 系统用户Controller控制器
 */
@RestController
@RequestMapping("/sys/user")
public class SysUserController {

    private static final Logger logger = LoggerFactory.getLogger(SysUserController.class);

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Value("${avatarImagesFilePath}")
    private String avatarImagesFilePath;

    @Autowired
    private OperationLogsService operationlogsService; // 注入操作日志服务
    /**
     * 添加或修改用户信息
     */
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('system:user:add') || hasAuthority('system:user:edit')")
    public R save(@RequestBody SysUser sysUser, HttpServletRequest request) {
        logger.info("添加或修改用户信息: {}", sysUser);
        if (sysUser.getId() == null || sysUser.getId() == -1) {
            sysUser.setCreateTime(new Date());
            sysUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getPassword()));
            sysUserService.save(sysUser);

            // 记录操作日志
            logOperation(request, "添加用户", "POST /sys/user/save", sysUser.toString(), "成功");
        } else {
            sysUser.setUpdateTime(new Date());
            sysUserService.updateById(sysUser);

            // 记录操作日志
            logOperation(request, "修改用户", "POST /sys/user/save", sysUser.toString(), "成功");
        }
        return R.ok();
    }
    /**
     * 更新用户密码
     */
    @PostMapping("/updateUserPwd")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public R updateUserPwd(@RequestBody SysUser sysUser, HttpServletRequest request) {
        logger.info("更新用户 {} 的密码", sysUser.getId());
        SysUser currentUser = sysUserService.getById(sysUser.getId());
        if (bCryptPasswordEncoder.matches(sysUser.getOldPassword(), currentUser.getPassword())) {
            currentUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getNewPassword()));
            sysUserService.updateById(currentUser);

            // 记录操作日志
            logOperation(request, "更新用户密码", "POST /sys/user/updateUserPwd", sysUser.toString(), "成功");
            return R.ok();
        } else {
            return R.error("输入旧密码错误！");
        }
    }
    /**
     * 上传用户头像图片
     */
    @RequestMapping("/uploadImage")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public Map<String, Object> uploadImage(MultipartFile file, HttpServletRequest request) throws Exception {
        logger.info("上传用户头像图片: {}", file.getOriginalFilename());
        Map<String, Object> resultMap = new HashMap<>();
        if (!file.isEmpty()) {
            String originalFilename = file.getOriginalFilename();
            String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));
            String newFileName = DateUtil.getCurrentDateStr() + suffixName;
            FileUtils.copyInputStreamToFile(file.getInputStream(), new File(avatarImagesFilePath + newFileName));
            resultMap.put("code", 0);
            resultMap.put("msg", "上传成功");
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("title", newFileName);
            dataMap.put("src", "image/userAvatar/" + newFileName);
            resultMap.put("data", dataMap);

            // 记录操作日志
            logOperation(request, "上传用户头像", "POST /sys/user/uploadImage", file.getOriginalFilename(), "成功");
        }
        return resultMap;
    }
    /**
     *更新用户头像
     */
    @RequestMapping("/updateAvatar")
//    @PreAuthorize("hasAuthority('system:user:edit')")
    public R updateAvatar(@RequestBody SysUser sysUser, HttpServletRequest request) {
        logger.info("更新用户 {} 的头像", sysUser.getId());

        // 检查 sysUser.getAvatar() 是否为完整的 URL
        if (!sysUser.getAvatar().startsWith("http")) {
            return R.error("头像 URL 不合法");
        }

        // 更新用户头像
        SysUser currentUser = sysUserService.getById(sysUser.getId());
        currentUser.setUpdateTime(new Date());
        currentUser.setAvatar(sysUser.getAvatar()); // 存储完整的 URL
        sysUserService.updateById(currentUser);

        // 记录操作日志
        logOperation(request, "更新用户头像", "POST /sys/user/updateAvatar", sysUser.toString(), "成功");
        return R.ok();
    }
    /**
     * 根据条件分页查询用户信息
     */
    @RequestMapping("/list")
    @PreAuthorize("hasAuthority('system:user:query')")
    public R list(@RequestBody PageBean pageBean, HttpServletRequest request) {
        logger.info("根据条件分页查询用户信息: {}", pageBean);
        String query = pageBean.getQuery().trim();
        Page<SysUser> pageResult = sysUserService.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()),
                new QueryWrapper<SysUser>().like(StringUtil.isNotEmpty(query), "username", query));
        List<SysUser> userList = pageResult.getRecords();
        for (SysUser user : userList) {
            List<SysRole> roleList = sysRoleService.list(new QueryWrapper<SysRole>().inSql("id", "select role_id from sys_user_role where user_id=" + user.getId()));
            user.setSysRoleList(roleList);
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("userList", userList);
        resultMap.put("total", pageResult.getTotal());

        // 记录操作日志
        logOperation(request, "查询用户列表", "POST /sys/user/list", pageBean.toString(), "成功");
        return R.ok(resultMap);
    }
    /**
     * 根据ID查询用户信息
     */
    @GetMapping("/{id}")
//    @PreAuthorize("hasAuthority('system:user:query')")
    public R findById(@PathVariable(value = "id") Integer id, HttpServletRequest request) {
        logger.info("根据ID查询用户信息: {}", id);
        SysUser sysUser = sysUserService.getById(id);
        Map<String, Object> map = new HashMap<>();
        map.put("sysUser", sysUser);

        // 记录操作日志
        logOperation(request, "查询用户信息", "GET /sys/user/{id}", "ID: " + id, "成功");
        return R.ok(map);
    }
    /**
     * 验证用户名是否存在
     */
    @PostMapping("/checkUserName")
    @PreAuthorize("hasAuthority('system:user:query')")
    public R checkUserName(@RequestBody SysUser sysUser, HttpServletRequest request) {
        logger.info("验证用户名 {} 是否存在", sysUser.getUsername());
        if (sysUserService.getByUsername(sysUser.getUsername()) == null) {
            // 记录操作日志
            logOperation(request, "验证用户名是否存在", "POST /sys/user/checkUserName", sysUser.toString(), "成功");
            return R.ok();
        } else {
            return R.error();
        }
    }
    /**
     * 删除用户信息
     */
    @Transactional
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('system:user:delete')")
    public R delete(@RequestBody Long[] ids, HttpServletRequest request) {
        logger.info("删除用户信息: {}", Arrays.toString(ids));
        sysUserService.removeByIds(Arrays.asList(ids));
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("user_id", ids));

        // 记录操作日志
        logOperation(request, "删除用户", "POST /sys/user/delete", Arrays.toString(ids), "成功");
        return R.ok();
    }
    /**
     * 重置用户密码
     */
    @GetMapping("resetPassword/{id}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public R resetPassword(@PathVariable(value = "id") Integer id, HttpServletRequest request) {
        logger.info("重置用户 {} 的密码", id);
        SysUser sysUser = sysUserService.getById(id);
        sysUser.setPassword(bCryptPasswordEncoder.encode(Constant.DEFAULT_PASSWORD));
        sysUser.setUpdateTime(new Date());
        sysUserService.updateById(sysUser);

        // 记录操作日志
        logOperation(request, "重置用户密码", "GET /sys/user/resetPassword/{id}", "ID: " + id, "成功");
        return R.ok();
    }
    /**
     * 更新用户状态
     */
    @GetMapping("updateStatus/{id}/status/{status}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public R updateStatus(@PathVariable(value = "id") Integer id, @PathVariable(value = "status") String status, HttpServletRequest request) {
        logger.info("更新用户 {} 的状态为 {}", id, status);
        SysUser sysUser = sysUserService.getById(id);
        sysUser.setStatus(status);
        sysUserService.saveOrUpdate(sysUser);

        // 记录操作日志
        logOperation(request, "更新用户状态", "GET /sys/user/updateStatus/{id}/status/{status}", "ID: " + id + ", Status: " + status, "成功");
        return R.ok();
    }
    /**
     * 为用户授权角色
     */
    @Transactional
    @PostMapping("/grantRole/{userId}")
    @PreAuthorize("hasAuthority('system:user:role')")
    public R grantRole(@PathVariable("userId") Long userId, @RequestBody Long[] roleIds, HttpServletRequest request) {
        logger.info("为用户 {} 授权角色: {}", userId, Arrays.toString(roleIds));
        List<SysUserRole> userRoleList = new ArrayList<>();
        Arrays.stream(roleIds).forEach(r -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setRoleId(r);
            sysUserRole.setUserId(userId);
            userRoleList.add(sysUserRole);
        });
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id", userId));
        sysUserRoleService.saveBatch(userRoleList);

        // 记录操作日志
        logOperation(request, "授权用户角色", "POST /sys/user/grantRole/{userId}", "User ID: " + userId + ", Role IDs: " + Arrays.toString(roleIds), "成功");
        return R.ok();
    }

    private void logOperation(HttpServletRequest request, String operation, String method, String params, String result) {
        Operationlogs log = new Operationlogs();
        log.setUsername(getCurrentUsername());
        log.setOperation(operation);
        log.setMethod(method);
        log.setParams(params);
        log.setResult(result);
        log.setElapsedTime(0L); // 可以计算实际耗时
        log.setCreateTime(new Date());
        log.setIpAddress(request.getRemoteAddr());
        log.setStatus("OK");
        operationlogsService.logOperation(log);
    }

    private String getCurrentUsername() {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            return ((UserDetails) principal).getUsername();
        } else {
            return principal.toString();
        }
    }

    /**
     * 获取当前登录用户信息
     * @return 当前登录用户信息
     */
    @GetMapping("/current")
    public R getCurrentUser() {
        // 获取当前登录用户的用户名
        String username = getCurrentUsername();
        if (username == null) {
            return R.error(401, "用户未登录");
        }

        // 根据用户名查询用户信息
        SysUser sysUser = sysUserService.getByUsername(username);
        if (sysUser == null) {
            return R.error(404, "用户不存在");
        }

        Map<String, Object> map = new HashMap<>();
        map.put("sysUser", sysUser);

       // 记录操作日志
//       logOperation("获取当前登录用户信息", "GET /sys/user/current", "用户名: " + username, "成功");
        return R.ok(map);
    }

}